package com.pro.common.api.depencies;

import com.pro.common.api.R;
import com.pro.framework.api.util.ExceptionUtil;
import com.pro.framework.api.util.JSONUtils;
import com.pro.framework.api.util.StrUtils;
import feign.FeignException;
import feign.RetryableException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.ByteBuffer;

/**
 * 异常处理器
 */
@RestControllerAdvice
@Slf4j
@AllArgsConstructor
@Order(1)  // 优先级较高
public class ExceptionHandlerFeign {


    @ExceptionHandler(FeignException.class)
    public R handleException(HttpServletRequest request, FeignException e) {
        byte[] body = byteBufferToArray(e.responseBody().orElse(null));

        // 获取请求 URL
        String feignRequestUrl = e.request() != null ? e.request().url() : "unknown";

        // 构造错误日志信息
        String bodyStr = null == body ? null : new String(body);
        String errMsg = e instanceof RetryableException ? "RetryableException" : ExceptionUtil.logThrowable(e, false);
        String errorMessage = String.format("Feign 调用异常：服务地址 [%s]，请求 URI [%s]，响应内容：%s",
                feignRequestUrl,
                request.getRequestURI(),
//                ""
//                bodyStr
                StrUtils.or(bodyStr, "") + errMsg
        );

        log.error(errorMessage);
        if (bodyStr == null) {
            return R.fail(e.getMessage());
        } else {
            return JSONUtils.fromString(bodyStr, R.class);
        }
//        return JSONUtils.fromString(bodyStr, R.class);
    }

    public static byte[] byteBufferToArray(ByteBuffer buffer) {
        if (buffer == null) {
            return null;
        }
        // 获取 ByteBuffer 的剩余数据大小
        byte[] byteArray = new byte[buffer.remaining()];

        // 从 ByteBuffer 中读取所有数据到 byte[] 中
        buffer.get(byteArray);

        return byteArray;
    }


}
